<?php
/** 
 * EGP Framework
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */

!defined('EGP_LIB_DIR') && die('Access Deny!');

/**
 * 文本分词
 *
 * @package    classes
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */
abstract class EGP_Text_Segment_Abstract
{

    /**
     * 全角/半角替换
     *
     * @var array
     */
    protected $_replace = array(
        '０' => '0', '１' => '1', '２' => '2', '３' => '3', '４' => '4',
        '５' => '5', '６' => '6', '７' => '7', '８' => '8', '９' => '9',
        'Ａ' => 'A', 'Ｂ' => 'B', 'Ｃ' => 'C', 'Ｄ' => 'D', 'Ｅ' => 'E',
        'Ｆ' => 'F', 'Ｇ' => 'G', 'Ｈ' => 'H', 'Ｉ' => 'I', 'Ｊ' => 'J',
        'Ｋ' => 'K', 'Ｌ' => 'L', 'Ｍ' => 'M', 'Ｎ' => 'N', 'Ｏ' => 'O',
        'Ｐ' => 'P', 'Ｑ' => 'Q', 'Ｒ' => 'R', 'Ｓ' => 'S', 'Ｔ' => 'T',
        'Ｕ' => 'U', 'Ｖ' => 'V', 'Ｗ' => 'W', 'Ｘ' => 'X', 'Ｙ' => 'Y',
        'Ｚ' => 'Z', 'ａ' => 'a', 'ｂ' => 'b', 'ｃ' => 'c', 'ｄ' => 'd',
        'ｅ' => 'e', 'ｆ' => 'f', 'ｇ' => 'g', 'ｈ' => 'h', 'ｉ' => 'i',
        'ｊ' => 'j', 'ｋ' => 'k', 'ｌ' => 'l', 'ｍ' => 'm', 'ｎ' => 'n',
        'ｏ' => 'o', 'ｐ' => 'p', 'ｑ' => 'q', 'ｒ' => 'r', 'ｓ' => 's',
        'ｔ' => 't', 'ｕ' => 'u', 'ｖ' => 'v', 'ｗ' => 'w', 'ｘ' => 'x',
        'ｙ' => 'y', 'ｚ' => 'z',
        "\r\n" => ' ', "\r" => ' ', "\n" => ' ', '　' => ' ',
    );

    /**
     * 过滤字符
     *
     * @var array
     */
    protected $_filter = array(
        '!', "'", '"', '#', '$', '%', '&', '(', ')', '[', ']', '*', '+', ',',
        '.', '-', '/', ':', ';', '<', '>', '?', '@', '\\', '^', '﹕', '_', '`',
        '{', '}', '|', '~', '¤', '§', '¨', '°', '±', '·', '×', '÷', 'ǹ', 'ˇ',
        'ˉ', 'Θ', 'Ψ', 'я', '—', '―', '‖', '‘', '’', '“', '”', '‥', '…',
        '‰', '′', '″', '※', '℃', '℅', '℉', '№', '℡', 'Ⅰ', 'Ⅱ', 'Ⅲ',
        'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ', 'Ⅹ', 'Ⅺ', 'Ⅻ', 'ⅰ', 'ⅱ', 'ⅲ',
        'ⅳ', 'ⅴ', 'ⅵ', 'ⅶ', 'ⅷ', 'ⅸ', 'ⅹ', '←', '↑', '→', '↓', '↖',
        '↗', '↘', '↙', '∈', '∏', '∑', '∕', '√', '∝', '∞', '∟', '∠',
        '∣', '∥', '∧', '∨', '∩', '∪', '∫', '∮', '∴', '∵', '∶', '∷',
        '∽', '≈', '≌', '≒', '≠', '≡', '≤', '≥', '≦', '≧', '≮', '≯',
        '⊕', '⊙', '⊥', '⊿', '⌒', '⌒＊', '①', '②', '③', '④', '⑤', '⑥',
        '⑦', '⑧', '⑨', '⑩', '⑴', '⑵', '⑶', '⑷', '⑸', '⑹', '⑺', '⑻',
        '⑼', '⑽', '⑾', '⑿', '⒀', '⒁', '⒂', '⒃', '⒄', '⒅', '⒆', '⒇',
        '⒈', '⒉', '⒊', '⒋', '⒌', '⒍', '⒎', '⒏', '⒐', '⒑', '⒒', '⒓',
        '⒔', '⒕', '⒖', '⒗', '⒘', '⒙', '⒚', '⒛', '─', '━', '│', '┃',
        '┄', '┅', '┆', '┇', '┈', '┉', '┊', '┋', '┌', '┍', '┎', '┏',
        '┐', '┑', '┒', '┓', '└', '┕', '┖', '┗', '┘', '┙', '┚', '┛',
        '├', '┝', '┞', '┟', '┠', '┡', '┢', '┣', '┤', '┥', '┦', '┧',
        '┨', '┩', '┪', '┫', '┬', '┭', '┮', '┯', '┰', '┱', '┲', '┳',
        '┴', '┵', '┶', '┷', '┸', '┹', '┺', '┻', '┼', '┽', '┾', '┿',
        '╀', '╁', '╂', '╃', '╄', '╅', '╆', '╇', '╈', '╉', '╊', '╋',
        '═', '║', '╒', '╓', '╔', '╕', '╖', '╗', '╘', '╙', '╚', '╛',
        '╜', '╝', '╞', '╟', '╠', '╡', '╢', '╣', '╤', '╥', '╦', '╧',
        '╨', '╩', '╪', '╫', '╬', '╭', '╭╮', '╮', '╯', '╰', '╱', '╲',
        '╳', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█', '▉', '▊', '▋',
        '▌', '▍', '▎', '▏', '░', '▒', '▓', '▔', '▕', '■', '□', '▣',
        '▤', '▥', '▦', '▧', '▨', '▩', '▪', '▫', '▬', '▲', '△', '▼', '▽',
        '◆', '◇', '◈', '○', '◎', '●', '◐', '◑', '◢', '◣', '◤', '◥', '★',
        '☆', '☉', '☎', '☏', '☜', '☞', '☺', '☻', '☼', '♀', '♂', '♠', '♡♢',
        '♣', '♤', '♥', '♦', '♧', '♨', '♩', '♪', '♫', '♬', '♭', '♯', '⺷',
        '⿰', '⿱', '⿲', '⿳', '⿴', '⿵', '⿶', '⿷', '⿸', '⿹', '⿺', '⿻',
        '、', '。', '〃', '々', '〆', '〇', '〈', '〉', '《', '》', '「', '」',
        '『', '』', '【', '】', '〒', '〓', '〔', '〕', '〖', '〗', '〝', '〞',
        '㈠', '㈡', '㈢', '㈣', '㈤', '㈥', '㈦', '㈧', '㈨', '㈩', '㈱', '㊣',
        '㎎', '㎏', '㎜', '㎝', '㎞', '㎡', '㏄', '㏎', '㏑', '㏒', '㏕', '卍',
        '卐', '', '︰', '︱', '︳', '︴', '︵', '︶', '︷', '︸', '︹', '︺',
        '︻', '︼', '︽', '︾', '︿', '﹀', '﹁', '﹂', '﹃', '﹄', '﹊', '﹋',
        '﹌', '﹍', '﹎', '﹏', '﹗', '﹢', '﹣', '﹤', '﹥', '！', '＂', '＃',
        '＄', '％', '＆', '＇', '（', '）', '＊', '＋', '，', '－', '．', '／',
        '：', '；', '＜', '＝', '＞', '？', '＠', '［', '＼', '］', '＾', '＿',
        '｀', '｛', '｜', '｝', '～', '￠', '￡', '￥',
    );

    /**
     * 构造方法
     *
     * @param  array  $options
     */
    public function __construct(array $options = array())
    {
        $this->setOptions($options);
    }

    /**
     * 设置参数配置
     *
     * @param  array  $options
     * @return EGP_Text_Segment_Abstract
     */
    public function setOptions(array $options = array())
    {
        foreach ($options as $key => $value) {
            $this->__set($key, $value);
        }

        return $this;
    }

    /**
     * 参数设置
     *
     * @param  mixed  $key
     * @param  mixed  $name
     */
    public function __set($key, $value)
    {
        $method = 'set' . ucfirst($key);
        if (method_exists($this, $method)) {
            $this->$method($value);
        } else {
            throw new EGP_Exception("无法对参数 '$key' 进行设置");
        }
    }

    /**
     * 设置分词文本
     *
     * @param  string  $text
     * @return EGP_Text_Segment_Abstract
     */
    abstract public function setText($text);

    /**
     * 获取分词单词集合
     *
     * @return array
     */
    abstract public function getWords();

    /**
     * 获取高频词
     *
     * @param  integer  $limit
     * @param  string   $attr
     * @param  integer  $times
     * @return array
     */
    abstract public function getTops($limit = 5, $attr = null, $times = 0);

}